package bank.driver.servlet;

import java.io.IOException;
import java.io.PrintWriter;
import java.util.Set;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import bank.InactiveException;
import bank.OverdrawException;
import bank.driver.local.LocalAccount;
import bank.driver.local.LocalBank;

public class BankServlet extends HttpServlet {

	private LocalBank bank;

	public BankServlet() {
		super();
		this.bank = new LocalBank();
	}

	@Override
	public void doGet(HttpServletRequest request, HttpServletResponse response)
			throws IOException, ServletException {
		response.setContentType("text/plain");
		PrintWriter out = response.getWriter();

		String action = getAction(request);

		if ("createAccount".equals(action)) {
			String owner = request.getParameter("owner");
			String number = this.bank.createAccount(owner);
			out.write(number);
		} else if ("getAccount".equals(action)) {
			String number = request.getParameter("number");
			LocalAccount acc = this.bank.getAccount(number);
			if(acc != null){
				out.write(acc.getOwner() + "&" + acc.getNumber());
			} else {
				out.write("null");
			}
		} else if ("getAccountNumbers".equals(action)) {
			Set<String> nrs = this.bank.getAccountNumbers();
			int i = 0;
			for (String nr : nrs) {
				out.write(nr);
				i++;
				if(i<nrs.size()){
					out.write("&");
				}
			}
		} else if ("removeAccount".equals(action)) {
			String number = request.getParameter("number");
			Boolean removed = this.bank.removeAccount(number);
			out.write(removed.toString());
		} else if ("transfer".equals(action)) {
			String numberA = request.getParameter("numberA");
			String numberB = request.getParameter("numberB");
			Double amount = Double.valueOf(request.getParameter("amount"));
			try {
				this.bank.transfer(this.bank.getAccount(numberA), this.bank
						.getAccount(numberB), amount);
				out.write("ok");
			} catch (IllegalArgumentException e1) {
				out.write("IllegalArgumentException");
			} catch (OverdrawException e1) {
				out.write("OverdrawException");
			} catch (InactiveException e1) {
				out.write("InactiveException");
			}
		} else if ("deposit".equals(action)){
			String number = request.getParameter("number");
			double amount = Double.valueOf(request.getParameter("amount"));
			LocalAccount acc = this.bank.getAccount(number);
			if (acc != null){
				try {
					this.bank.getAccount(number).deposit(amount);
				} catch (IllegalArgumentException e) {
					out.write("IllegalArgumentException");
				} catch (InactiveException e) {
					out.write("InactiveException");
				}
			} else  {
				out.write("InactiveException");
			}
			
		} else if ("getBalance".equals(action)){
			String number = request.getParameter("number");
			LocalAccount acc = this.bank.getAccount(number);
			if(acc != null && acc.isActive()){
				double balance = acc.getBalance();
				out.write(Double.toString(balance));
			} else {
				out.write(Double.toString(0.0));
			}			
		} else if ("isActive".equals(action)){
			String number = request.getParameter("number");
			LocalAccount acc = this.bank.getAccount(number);
			if(acc != null){
				boolean active = acc.isActive();
				out.write(Boolean.toString(active));
			} else {
				out.write(Boolean.toString(false));
			}	
		} else if ("withdraw".equals(action)){
			String number = request.getParameter("number");
			double amount = Double.valueOf(request.getParameter("amount"));
			LocalAccount acc = this.bank.getAccount(number);
			if(acc != null){
				try {
					acc.withdraw(amount);
					out.write("ok");
				} catch (IllegalArgumentException e) {
					out.write("IllegalArgumentException");
				} catch (OverdrawException e) {
					out.write("OverdrawException");
				} catch (InactiveException e) {
					out.write("InactiveException");
				}
			} else {
				out.write("InactiveException");
			}
		}		 
	}

	private String getAction(HttpServletRequest request) {
		String requestUri = request.getRequestURI();
		String contextPath = request.getContextPath();
		StringBuffer uri = new StringBuffer(requestUri);
		return uri.substring(contextPath.length() + 1);
	}
}